<template>
  <div>
    <el-container>
      <el-main>
        <el-header class="header-class" height="22">
          <div class="header-text">{{text.roleMaintenance}}</div>
        </el-header>
        <div class="panel-border">
          <el-row>
            <div class="add-button-class">
              <el-button @click="onAddRole">{{text.addRole}}</el-button>
            </div>
          </el-row>
          <el-table border class="table" fit :data="roleTableData" style="width: 98%" :size="tableSize"
                    @row-click="onRoleTableRowClick"
                    empty-text="No record found" :highlight-current-row=true>
            <el-table-column label="#" type="index" :index="indexCalculate">
            </el-table-column>
            <el-table-column label="Role Name" prop="roleName">
            </el-table-column>
            <el-table-column label="Role Description" prop="roleDesc">
            </el-table-column>
            <el-table-column label="Created At" prop="createdAt">
            </el-table-column>
            <el-table-column label="Last Updated At" prop="updatedAt">
            </el-table-column>
            <el-table-column label="Last Updated By" prop="updatedBy.domainId">
            </el-table-column>
            <el-table-column label="Action">
              <template slot-scope="scope">
                <el-button size="mini" @click="handleEditRoleButton(scope.$index, scope.row)" icon="el-icon-edit">Edit
                </el-button>
                <el-button size="mini" type="danger" @click="handleDeleteRoleButton(scope.$index, scope.row)"
                           icon="el-icon-delete">
                  Delete
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <el-container>
            <div class="pagination">
              <el-pagination :current-page="roleCurrentPage" layout="prev, pager, next"
                             :total="rolePaginationConfig.total" :page-size="rolePaginationConfig.limit"
                             @current-change="onRolePageChange">
              </el-pagination>
            </div>
          </el-container>
          <el-dialog :title="editRoleDialogConfig.title" :visible.sync="editRoleDialogConfig.isVisible"
                     :width="editRoleDialogConfig.width" center>
            <edit-role-form ref="roleForm"></edit-role-form>
            <span slot="footer" class="dialog-footer">
          <el-button @click="setIsEditRoleDialogVisible(false)">Cancel</el-button>
          <el-button type="primary" @click="submitEditRoleFormData">Save</el-button>
        </span>
          </el-dialog>
        </div>
      </el-main>
    </el-container>
    <el-container>
      <el-main>
        <el-header class="header-class" height="22">
          <div class="header-text">{{text.roleAuthorization}}</div>
        </el-header>
        <div class="panel-border">
          <div class="add-button-class">
            <el-button @click="onAddRoleAuthorization">{{text.addRoleAuthorization}}</el-button>
          </div>
          <el-table border class="table" :data="roleAuthorizationTableData" style="width: 98%" :size="tableSize">
            <el-table-column label="#" type="index">
            </el-table-column>
            <el-table-column label="User Id" prop="userName">
            </el-table-column>
            <el-table-column label="User Name" prop="userDesc" :width="userNameColumnWidth">
            </el-table-column>
            <el-table-column label="Created At" prop="createdAt">
            </el-table-column>
            <el-table-column label="Created By" prop="createdBy.domainId">
            </el-table-column>
            <el-table-column label="Operation">
              <template slot-scope="scope">
                <el-button size="mini" type="danger"
                           @click="handleDeleteRoleAuthorizationButton(scope.$index, scope.row)"
                           icon="el-icon-delete">
                  Delete
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-main>
    </el-container>
    <el-dialog :title="addRoleAuthorizationDialogConfig.title"
               :visible.sync="addRoleAuthorizationDialogConfig.isVisible"
               :width="addRoleAuthorizationDialogConfig.width" center>
      <add-role-authorization-form :roleAuthorizationTableData.sync="roleAuthorizationTableData"
                                   ref="roleAuthorizationForm"></add-role-authorization-form>
      <span slot="footer" class="dialog-footer">
          <el-button @click="setIsEditRoleAuthorizationDialogVisible(false)">Cancel</el-button>
          <el-button type="primary" @click="submitAddRoleAuthorizationFormData">Save</el-button>
        </span>
    </el-dialog>
  </div>
</template>

<script>
import roleService from '@/service/role'
import editRoleForm from './EditRoleForm.vue'
import addRoleAuthorizationForm from './AddRoleAuthorizationForm.vue'
import util from '@/common/js/util'

const INVALID_ROLD_ID = -1
const FIRST_PAGE_NUMBER = 1
const ADD_ROLE = 'addRole'
const EDIT_ROLE = 'editRole'

export default {
  components: {
    editRoleForm,
    addRoleAuthorizationForm
  },

  data() {
    return {
      tableSize: 'mini',
      roleTableData: [],
      roleAuthorizationTableData: [],
      roleAndAuthorization: {},
      userNameColumnWidth: '370',
      selectedRoleId: INVALID_ROLD_ID,
      editRoleDialogConfig: {
        title: 'Add Role Information',
        isVisible: false,
        width: '500px'
      },
      addRoleAuthorizationDialogConfig: {
        title: 'Add Role Authorization',
        isVisible: false,
        width: '500px'
      },
      rolePaginationConfig: {
        total: 0,
        limit: 5
      },
      roleCurrentPage: 1,
      roleOperationType: '',
      text: {
        roleMaintenance: 'Role Maintenance',
        addRole: 'Add Role',
        roleAuthorization: 'Role Authorization Maintenance',
        addRoleAuthorization: 'Add Role Authorization'
      }
    }
  },

  methods: {
    async loadRoleAndAuthorizationData(pageNumber) {
      let sortOrderList = []
      let sortRule = {
        property: 'roleName',
        direction: 'ASC'
      }
      sortOrderList.push(sortRule)
      let loadCondition = {
        page: pageNumber,
        start: 0,
        limit: this.rolePaginationConfig.limit,
        sortOrderList: sortOrderList
      }
      return await roleService.getRoleAndAuthorization(loadCondition)
    },

    onRolePageChange(pageNumber) {
      this.getRoleTableData(pageNumber)
      this.roleCurrentPage = pageNumber
    },

    async getRoleTableData(pageNumber) {
      let roleAndAuthorizationData = await this.loadRoleAndAuthorizationData(pageNumber)
      this.roleTableData = roleAndAuthorizationData.content
      this.rolePaginationConfig.total = roleAndAuthorizationData.totalElements
    },

    onRoleTableRowClick(role) {
      this.setSelectedRoleId(role.id)
      this.refreshRoleAuthorizationTable()
    },

    genRoleAuthorizationTableDataByRoleId(roleId) {
      let filteredData = this.roleTableData.filter((currentValue) => { if (currentValue.id === roleId) return currentValue.roleAuths })
      if (filteredData.length > 0) {
        this.roleAuthorizationTableData = filteredData[0].roleAuths
      }
    },

    setSelectedRoleId(roleId) {
      this.selectedRoleId = roleId
    },

    getSelectedRoleId() {
      return this.selectedRoleId
    },

    onAddRole() {
      this.setDataToRoleForm({})
      this.roleOperationType = ADD_ROLE
    },

    handleEditRoleButton(index, role) {
      this.setDataToRoleForm(role)
      this.roleOperationType = EDIT_ROLE
    },

    async handleDeleteRoleButton(index, role) {
      this.$confirm(`Are you sure you want to delete this role <strong> ${role.roleName} </strong>?`, 'Warning', {
        dangerouslyUseHTMLString: true,
        confirmButtonText: 'Delete',
        cancelButtonText: 'Cancel',
        type: 'warning',
        callback: (action) => {
          if (action === 'confirm') {
            roleService.delRole(role.id)
            this.getRoleTableData(FIRST_PAGE_NUMBER)
            this.reset()
          }
        }
      }).then(() => {
        this.$message({
          type: 'success',
          message: 'Delete successful.'
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: 'Cancel delete.'
        })
      })
    },

    setDataToRoleForm: function (data) {
      this.setIsEditRoleDialogVisible(true)
      let tempObject = util.deepClone(data)
      this.$nextTick(() => {
        this.$refs.roleForm.setFormModel(tempObject)
      })
    },

    onAddRoleAuthorization() {
      let selectedRoleId = this.getSelectedRoleId()
      if (selectedRoleId === INVALID_ROLD_ID) {
        this.$message({
          message: 'Please select <strong> role information </strong> first.',
          dangerouslyUseHTMLString: true,
          type: 'warning'
        })
      } else {
        this.setIsEditRoleAuthorizationDialogVisible(true)
        this.$nextTick(() => {
          this.$refs.roleAuthorizationForm.setFormModel({})
        })
      }
    },

    setIsEditRoleDialogVisible(isVisible) {
      this.editRoleDialogConfig.isVisible = isVisible
    },

    setIsEditRoleAuthorizationDialogVisible(isVisible) {
      this.addRoleAuthorizationDialogConfig.isVisible = isVisible
    },

    async submitEditRoleFormData() {
      let role = this.$refs.roleForm.getFormModel()
      if (role.roleName.trim() === '') {
        return false
      } else {
        if (this.roleOperationType === ADD_ROLE) {
          await roleService.addRole(role)
        } else {
          await roleService.updateRole(role)
        }
        this.reset()
        this.setIsEditRoleDialogVisible(false)
      }
    },

    async submitAddRoleAuthorizationFormData() {
      let validateResult = this.$refs.roleAuthorizationForm.getValidateResult()
      let domainIdOrGroupName = this.$refs.roleAuthorizationForm.getFormModel().domainIdOrGroupName
      if (validateResult) {
        let params = {roleId: this.getSelectedRoleId(), domainIdOrGroupName: domainIdOrGroupName}
        await roleService.addRoleAuthorization(params)
        this.setIsEditRoleAuthorizationDialogVisible(false)
        this.refreshRoleAuthorizationTable()
        return true
      } else {
        if (domainIdOrGroupName) {
          this.$message({
            message: `Can't add <strong> ${domainIdOrGroupName} </strong> twice.`,
            dangerouslyUseHTMLString: true,
            type: 'error'
          })
        }
        return false
      }
    },

    async refreshRoleAuthorizationTable() {
      this.roleAuthorizationTableData = await roleService.getRoleAuthorizationByRoleId(this.getSelectedRoleId())
    },

    async reset() {
      this.roleCurrentPage = 1
      this.roleTableData = []
      this.loadRoleAndAuthorizationData(FIRST_PAGE_NUMBER)
      this.getRoleTableData(FIRST_PAGE_NUMBER)
      this.roleAuthorizationTableData = []
    },

    indexCalculate(index) {
      return (this.roleCurrentPage - 1) * this.rolePaginationConfig.limit + index + 1
    },

    handleDeleteRoleAuthorizationButton(index, roleAuthorization) {
      this.$confirm(`Are you sure you want to delete this role <br><strong>${roleAuthorization.userDesc}</strong>?`, 'Warning', {
        dangerouslyUseHTMLString: true,
        confirmButtonText: 'Delete',
        cancelButtonText: 'Cancel',
        type: 'warning',
        callback: async (action) => {
          if (action === 'confirm') {
            await roleService.delRoleAuthorization(roleAuthorization.id)
            this.refreshRoleAuthorizationTable()
          }
        }
      }).then(() => {
        this.$message({
          type: 'success',
          message: 'Delete successful.'
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: 'Cancel delete.'
        })
      })
    }
  },
  mounted() {
    this.getRoleTableData(FIRST_PAGE_NUMBER)
  }
}
</script>

<style scoped lang="scss">
  @import './../../../common/css/base.scss';

  .add-button-class {
    margin-top: 10px;
    margin-left: 15px;
  }

  .pagination {
    align-items: center;
    margin-left: auto;
    margin-right: auto;
  }

  .panel-border {
    border: 1px solid $base-header-color;
  }

  .search-panel {
    height: 100px;
    margin: 10px;
    padding: 10px;
    border: 1px solid $base-header-color;
  }

  .table {
    margin: 15px;
  }

  .header-class {
    @include baseHeader(30px);
  }

  .header-text {
    color: #fff;
    padding-top: 5px;
    font-weight: bold;
  }

  .el-form-item.search-form-item {
    margin-bottom: 0;
  }

</style>
